package com.magold.logic;

import org.andengine.entity.shape.IAreaShape;
import org.andengine.extension.physics.box2d.PhysicsConnector;

import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.magold.logic.exception.SelfCollisionException;
import com.magold.physics.MagoldPhysicsConnector;
import com.magold.physics.PhysicsConnectorHolder;

public class LogicComponentFinder {
	
	public static MagoldPhysicsConnector findConnector(Body pBody) {
		return findConnector((IAreaShape) pBody.getUserData());
	}
	public static MagoldPhysicsConnector findConnector(IAreaShape pShape) {
		Object userData = pShape.getUserData();
		
		if (userData instanceof PhysicsConnectorHolder) {
			PhysicsConnectorHolder holder = ((PhysicsConnectorHolder) userData);
			
			return holder.findPhysicsConnector(pShape);
		}
		
		return null;
	}
	
	public static MagoldPhysicsConnector findConnector(ISpriteLogic pLogic, Contact pContact) throws SelfCollisionException {
		IAreaShape pShape = findShape(pLogic, pContact);
		
		return findConnector(pShape);
	}
	
	/**
	 * 
	 * @param pLogic
	 * @param pContact
	 * @return shape that is belonged to pLogic, and in pContact.
	 * @throws SelfCollisionException if both body was belonged to pLogic.
	 */
	public static IAreaShape findShape(ISpriteLogic pLogic, Contact pContact) throws SelfCollisionException {
		Body body = findBody(pLogic, pContact);
		
		if (body != null) {
			return (IAreaShape) body.getUserData();
		} else {
			return null;
		}
	}
	
	public static Fixture findFixture(ISpriteLogic pLogic, Contact pContact) throws SelfCollisionException {
		Fixture aFixture = pContact.getFixtureA();
		Fixture bFixture = pContact.getFixtureB();
		
		if (isA(pLogic, pContact)) {
			return aFixture;
		} else {
			return bFixture;
		}
	}
	
	public static Body findBody(ISpriteLogic pLogic, Contact pContact) throws SelfCollisionException {
		Body aBody = pContact.getFixtureA().getBody();
		Body bBody = pContact.getFixtureB().getBody();
		
		if (isA(pLogic, pContact)) {
			return aBody;
		} else {
			return bBody;
		}
	}
	
	private static boolean isA(ISpriteLogic pLogic, Contact pContact) throws SelfCollisionException {
		Body aBody = pContact.getFixtureA().getBody();
		Body bBody = pContact.getFixtureB().getBody();
		
		IAreaShape aShape = (IAreaShape) aBody.getUserData();
		IAreaShape bShape = (IAreaShape) bBody.getUserData();
		PhysicsConnector aConnector = pLogic.findPhysicsConnector(aShape);
		PhysicsConnector bConnector = pLogic.findPhysicsConnector(bShape);
		
		if (aConnector != null) return true;
		if (bConnector != null) return false;
		throw new SelfCollisionException();
	}
		
}
